#include "mainwindow.h"


MyWindow::MyWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    time = 100;
    buffer_size = 100;
    data = new ohe_framework::Spline(buffer_size);
    data->clear();
////////////////////////////////////////////////////////////////////////////////////    
    plot = ui->horizontal;
    plot->setLimits(-(double)buffer_size/25,
                               (double)time/1000,-50,50);
    plot->axis( KPlotWidget::BottomAxis )->setLabel( ("time in seconds") );
    plot->axis( KPlotWidget::LeftAxis )->setLabel( ("stagger(in cm)") );
    horizontal = new KPlotObject(Qt::red, KPlotObject::Lines,2);
    plot->addPlotObject(horizontal);
    plot->update();
///////////////////////////////////////////////////////////////////////////////////    
    plot = ui->vertical;
    plot->setLimits(-(double)buffer_size/25,
                               (double)time/1000,100,200);
    plot->axis( KPlotWidget::BottomAxis )->setLabel( ("time in seconds") );
    plot->axis( KPlotWidget::LeftAxis )->setLabel( ("height(in cm)") );
    vertical = new KPlotObject(Qt::red, KPlotObject::Lines,2);
    plot->addPlotObject(vertical);
    plot->update();
//////////////////////////////////////////////////////////////////////////////////    
    plot = ui->radius;
    plot->setLimits(-(double)buffer_size/25,
                               (double)time/1000,-1,20);
    plot->axis( KPlotWidget::BottomAxis )->setLabel(("time in seconds"));
    plot->axis( KPlotWidget::LeftAxis )->setLabel( ("radius(in cm)") );
    radius = new KPlotObject(Qt::red, KPlotObject::Lines,2);
    plot->addPlotObject(radius);
    plot->update();
///////////////////////////////////////////////////////////////////////////////////    
    ui->Start->setEnabled(false);
    ui->OpenFile->setEnabled(true);
    ui->Stop->setEnabled(false);
    ui->Pause->setEnabled(false);
    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(on_updateImageGraph()));
///////////////////////////////////////////////////////////////////////////////////
    vectors = new ohe_framework::CircularBufferPoint(buffer_size);    
    roi_range.x = roi_range.y = 400;
    center_x = center_y = 0;
}

void MyWindow::on_OpenFile_clicked()
{
    QString filename = QFileDialog::getExistingDirectory(this,
                                                    tr("Open File"),
                                                    "/home/vinay/BTP/btp-mtp/");
    if(!filename.isEmpty())
    {
        folder_name = filename.toStdString();
        current_filename = folder_name.substr(folder_name.find_last_of('/'));
        ui->Start->setEnabled(true);
        ui->Stop->setEnabled(false);
    }
}

void MyWindow::on_Start_clicked()
{
    frames_no = 1;
    //video_input.open(current_filename);
    if(/*video_input.isOpened()*/getNextFrame(image_raw))
    {
        //image_size= cv::Size((int)video_input.get(CV_CAP_PROP_FRAME_WIDTH),
         //              (int)video_input.get(CV_CAP_PROP_FRAME_HEIGHT));
        image_size = cv::Size(image_raw.cols,image_raw.rows);
        video_being_processed = true;
        ui->Start->setEnabled(false);
        ui->OpenFile->setEnabled(false);
        ui->Stop->setEnabled(true);
        ui->Pause->setEnabled(true);
        center_x = image_size.width/2;
        center_y = image_size.height/2;
        image_raw = cv::Mat::zeros(image_size,CV_8UC3);
        image_processed = cv::Mat::zeros(image_size,CV_8UC3);
        image_Qimage = cv::Mat::zeros(cv::Size(400,250),CV_8UC3);
        images.push_back(ohe_framework::ImageMatrixUchar());
        images.push_back(ohe_framework::ImageMatrixUchar());
        images.push_back(ohe_framework::ImageMatrixUchar());
        images[0].matToMatrix(image_raw);
        images[1].matToMatrix(image_raw);
        images[2].matToMatrix(image_raw);
        wire_found = false;
        roi_origin.y=roi_origin.x=0;
        roi_pre_origin = roi_origin;
        roi_range.x = images[0].getCols();
        roi_range.y = images[0].getRows();
        wire_points.push_back(ohe_framework::Point(0,0));
        wire_points.push_back(ohe_framework::Point(0,0));
        wire_points.push_back(ohe_framework::Point(0,0));
        count = 0;
        ohe_framework::setTimeGap(1.0);
        timer->start(time);
        file.open((folder_name+".ohe").c_str());
        file1.open((folder_name+"_radon.txt").c_str());
        x = 0.00;
        count1 = 1;
        count_mast = 0;
        last_mast = false;
        //on_updateImageGraph();
    }
    else
    {
        QString name(current_filename.c_str());
        QMessageBox::question(  this,
                                tr("Error"),
                                tr("Cannot open folder \"%1\"?").arg(name),
                                QMessageBox::Ok);
    } 
    //video_input.set()
}

void MyWindow::on_Stop_clicked()
{
    video_being_processed = false;
    wire_found = false;
    video_input.release();
    ui->OpenFile->setEnabled(true);
    ui->Start->setEnabled(true);
    ui->Stop->setEnabled(false);
    ui->Pause->setEnabled(false);
    timer->stop();
    roi_origin.x = roi_origin.y = 0;
    roi_pre_origin.x = roi_pre_origin.y = 0;
    center_x = center_y = 0;
    count =0;
    wire_points.clear();
    vectors->clear();
    image_raw.release();
    image_processed.release();
    image_Qimage.release();
    images.clear();
    data->clear();
    file.close();
    file1.close();
}

void MyWindow::on_Pause_clicked()
{
    if(video_being_processed)
    {
        video_being_processed = false;
    }
    else
    {
        video_being_processed = true;
    }
}

void MyWindow::on_updateImageGraph()
{
    if(video_being_processed)
    {
        std::clock_t start_time;
        start_time = clock();
        if(getNextFrame(image_raw))
        {
            images[0].matToMatrix(image_raw);
            image_processed = cv::Mat::zeros(image_size,CV_8UC3);
            images[1].matToMatrix(image_processed);
            images[2].matToMatrix(image_processed);
            roi_pre_origin = roi_origin;
            wire_found = ohe_framework::getNewPosition(images,roi_origin,
                                                       roi_range,wire_points,file1);
            double x_ = x;
            x+=0.60;
            displayImages();
            if(wire_found)
            {
                roi_range.x = 300;
                roi_range.y = 300;
                vectors->write((wire_points.at(0)),(wire_points.at(1)),(wire_points.at(2)));
                double height = (wire_points[0]).y-(wire_points[1]).y;
                height = 192.767-1.11617*height+.00376203*height*height
                        -0.00000549338*height*height*height;
                double stagger = ((double)((double)(wire_points[0]).x
                                           +(double)(wire_points[1]).x
                                           -(double)768)/2)*.3*height/150;
                data->addPoint(x,height,stagger,12);
                if(count<buffer_size)
                {
                    count++;
                }
                else
                {
//                    if(count1==1)
                    {
                        float* heights = new float[12];
                        float* staggers = new float[12];
                        data->getPoints(heights,staggers,0);
                        for(int j=1;j<12;j++)
                        {
                            x_+=0.05;
                            file<<x_<<"\t"<<staggers[j]<<"\t"<<heights[j]<<std::endl;
                        }
                        file<<x<<"\t"<<stagger<<"\t"<<height<<std::endl;
                        delete heights;
                        delete staggers;
                    }
/*                    else
//                    {
//                        file<<x_<<"\t"<<cur_stagger<<"\t"<<cur_height<<std::endl;
//                        for(int i = count1-1;i>=0;i--)
//                        {
//                            for(int j=0;j<13;j++)
//                            {
//                                x_+=0.05;
//                                file<<x_<<"\t"<<cur_stagger<<"\t"<<cur_height<<std::endl;
//                            }
//                            x_+=0.05;
//                            file<<x_<<"\t"<<cur_stagger<<"\t"<<cur_height<<std::endl;
//                        }
//                        x_+=0.05;
//                        file<<x_<<"\t"<<cur_stagger<<"\t"<<cur_height<<std::endl;
//                        int k;
//                        std::cin>>k;
//                    }*/
                    displayGraph();
                }
                count1=1;
                cur_height = height;
                cur_stagger = stagger;
                if(release_mast==0)
                    last_mast = false;
                else
                    release_mast--;
            }
            else
            {
                count1++;
                data->addPoint(x,cur_height,cur_stagger,11);
                for(int j=0;j<11;j++)
                {
                    x_+=0.05;
                    file<<x_<<"\t"<<cur_stagger<<"\t"<<cur_height<<std::endl;
                }
                if((!last_mast))
                {
                    count_mast++;
                    last_mast = true;
                    release_mast = 20;
                }
            }
        }
        else
            on_Stop_clicked();
        clock_t end_time = clock();
        std::cout<<"execution time = "<<(double)(end_time-start_time)/(double)CLOCKS_PER_SEC<<"\t"<<"Mast count"<<count_mast<<"\t"<<std::endl;
    }
}

void MyWindow::displayGraph()
{
    KPlotObject *object = (ui->horizontal->plotObjects())[0];
    KPlotObject *object1 = (ui->vertical->plotObjects())[0];
    KPlotObject *object2 = (ui->radius->plotObjects())[0];
    int read_index = vectors->getWriteIndex();
    int i =0;
    object->clearPoints();
    object1->clearPoints();
    object2->clearPoints();
    ohe_framework::Point upper, lower, _radius;
    for( double t =0;i<buffer_size;i++,t -=(double)1/25 ) 
    {
         vectors->read(read_index-i,upper,lower,_radius);
         double height = upper.y-lower.y;
         height = 192.767-1.11617*height+.00376203*height*height
                 -0.00000549338*height*height*height;
         double stagger = ((double)((double)upper.x
                                    +(double)lower.x-(double)768)/2)*.3*height/150;
         object->addPoint(t,stagger);
         object1->addPoint(t,height);
         object2->addPoint(t,_radius.x);
    }
    ui->horizontal->update();
    ui->vertical->update();
    ui->radius->update();
}

void MyWindow::displayImages()
{
    /////////////////////////////////////////////////////////////////
    cv::resize(image_raw,image_Qimage,cv::Size(400,275));
    cv::cvtColor(image_Qimage,image_Qimage,CV_BGRA2RGB);
    QImage display1((uchar *)image_Qimage.data,image_Qimage.cols,
                    image_Qimage.rows,QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(display1));
    //////////////////////////////////////////////////////////////////
    images[2].matrixToMat(image_processed);
    cv::resize(image_processed,image_Qimage,cv::Size(400,275));
    cv::cvtColor(image_Qimage,image_Qimage,CV_BGRA2RGB);
    QImage display2((uchar *)image_Qimage.data,image_Qimage.cols,
                    image_Qimage.rows,QImage::Format_RGB888);
    ui->label_2->setPixmap(QPixmap::fromImage(display2));
    //////////////////////////////////////////////////////////////////
    images[1].matrixToMat(image_processed);
    cv::resize(image_processed,image_Qimage,cv::Size(400,275));
    cv::cvtColor(image_Qimage,image_Qimage,CV_BGRA2RGB);
    QImage display3((uchar *)image_Qimage.data,image_Qimage.cols,
                    image_Qimage.rows,QImage::Format_RGB888);
    ui->label_3->setPixmap(QPixmap::fromImage(display3));
    /////////////////////////////////////////////////////////////////////
}

bool MyWindow::getNextFrame(cv::Mat &img)
{
    std::string name = folder_name+current_filename;
    std::ostringstream convert;
    convert<<frames_no;
    if(frames_no<10)
    {
        name+=" 000";
        name+=convert.str();
        name+=".jpg";
    }
    else
    {
        if(frames_no<100)
        {
            name+=" 00";
            name+=convert.str();
            name+=".jpg";
        }
        else
        {
            if(frames_no<1000)
            {
                name+=" 0";
                name+=convert.str();
                name+=".jpg";
            }
            else
            {
                name+=" ";
                name+=convert.str();
                name+=".jpg";
            } 
        }
    }
    img = cv::imread(name.c_str(),CV_LOAD_IMAGE_COLOR);
    if(img.data)
    {
        frames_no++;
        return true; 
    }
    else
    {
        std::cout<<"can not read "<<name<<" "<<std::endl;
        return false;
    }
}

MyWindow::~MyWindow()
{
    std::cout<<"delteing "<<std::endl;
}

void MyWindow::closeEvent(QCloseEvent *)
{
    std::cout<<"closing"<<std::endl;
    if(video_being_processed)
    {
        on_Stop_clicked();
    }
    else
    { 
    }
}
